import java.io.*;
import java.net.*;
import java.util.*;

/**
 * The purpose of this interface is to provide the chat server. 
 * @author Tung Nguyen, Trung V Hoang, Rob Bernard, Justin Semmel
 * @see java.util.Observable
 * @since September 2012 
 */
public class MultiTCPServer
{
	/*  'MultiTCPServer.java'  created by: Team N3 for Swinburne Uni HET715s2/Dr. Recep Ulusoy, 2/10/2012 v0.0 (final)
	*   ===============================================================================
	*
	*   A simple Chat Server program that accepts TCP packets sent to it on Port 6666 by a client, then echos it back to that 
	*   client, ready for display.  It is adapted from a Lab program provided by Dr. Ulusoy.  Its main function is to allow easy
	*   development of a GUI Chat Client, by providing a simple 'target' for packets.  Only one client is served at a time.
	*
	*       NOTE:   a simple diagnostic log of Server activity is available on the CLI Window display.
	*   
	*   	Java Code Writers:  		Trung Hoang and Tung Nguyen       
	*	Embedded documentation:              Rob Bernard
	*	JavaDoc development:		Justin Semmel
	*
	*
	*  The full program requires the following to be present in a PC to operate:
	*  
	*        - An Ethernet Port, managed by the Windows O/S (or similar);
	*        - a Java Machine (pref. JRE6 or better) with the usual libraries (to run it - see User Manual), and ....
	*        - a User Manual in older 'WORD' format ('J715projectCLImanual.doc').
	*
	*
	*  VERBAL (STEPWISE) FLOWCHART FOR MAIN LOOP:
	*
	*	1.  Test if TCP Port 6666 is available for use  <------------
	*	2.  Loop waiting for new Client input packet                 |
	*	3.  Run Client communication thread process (ClientHandler)  |
	*	4.  Loop for more activity ----------------------------------
	*
	*
	*  CLASSES CALLED:  ServerSocket, ClientHandler, Scanner, PrintWriter
	*  ==============    Class and Method summary.  (done by Justin in JavaDocs?)
	*
	*
	*   ***  1.  Test if TCP Port 6666 is available for use  ***
	*            (sets port and error-handler up, then tries to access Port 6666)
	*/
	private static ServerSocket serverSocket;
	private static final int PORT = 6666;

	public static void main(String[] args) throws IOException
	{
		try
		{
			serverSocket = new ServerSocket(PORT);// Port access/setup attempt
		}
		catch (IOException ioEx)// Port access error-handler
		{
			System.out.println("\nUnable to set up port!");
			System.exit(1);// Exit to O/S with (testable)
		}

		/*
		*   ***  2.  Loop waiting for new Client input packet  ***
		*	(Diagnostic display on CLI Window when one comes)
		*/
		do
		{
			//Wait for client...
			Socket client = serverSocket.accept();

			System.out.println("\nNew client accepted.\n");

			/*
			*   ***  3.  Create Client communication thread  ***
			*	(Creates a thread to handle this client's comms & pass this thread's constructor a reference to that socket)
			*/
			ClientHandler t = new ClientHandler(client);
			t.start();
		/*
		*   ***  4.  Loop for more activity  ***
		*	(Returns to get fresh client attachments.  Note only one client served at a time, 'first come / best-
		*        dressed'.  When that client ends a session, control returns to here to loop to listen aagain).
		*/
		}while (true);
	}
}

/*
*       **********************************  End of MAIN Loop  ****************************************
*/
/**    Class ClientHandler
*    ===================
*    This code creates an echo of the Client message back to it, with the word 'ECHO:' used as a prompt. 
*    If the Client message contains the string '*END*' then a shutdown warning is sent to the Client, 
*    and control reverts to the Main Loop (above), waiting for a new Client to try to connect.
* 
*
*  VERBAL (STEPWISE) FLOWCHART FOR CLASS ClientHandler:
*
*	1.  Initiallise and test if Socket I/O works OK
*	2.  Reads input Socket and echos to output Socket <---|
*	3.  Checks for not 'End Message', if not then loop  -----|
*	4.  End Message received, so attempt end of connection  & return to caller 
*
*
*  CLASSES CALLED:  getInputStream(), getOutputStream(), ioEx.printStackTrace(), Scanner, PrintWriter
*  ==============    Class and Method summary.  (done by Justin in JavaDocs?)
*
*
*   ***  1.  Initiallise and test if Socket I/O works OK  ***
*            (sets Socket and Error-handler up, then tries to access Socket for I/O.  )
*
*/

class ClientHandler extends Thread
{
	private Socket client;
	private Scanner input;
	private PrintWriter output;

	public ClientHandler(Socket socket)
	{
		//Set up reference to associated socket...
		client = socket;

		try
		{
			input = new Scanner(client.getInputStream());
			output = new PrintWriter(
							client.getOutputStream(),true);
		}
		catch(IOException ioEx)
		{
			ioEx.printStackTrace();
		}
	}

	/**
	*   ***  2. Reads input Socket and echos to output Socket  ***
	*           (Runs I/O stream between Client and echo reply. Sets-up 'DO' loop for I/O)
	*/	
	public void run()
	{
		String received;
		do
		{
			//Accept message from client on
			//the socket's input stream...
			received = input.nextLine();

			//Echo message back to client on
			//the socket's output stream...
			output.println("ECHO: " + received);

		/*
		*   ***  3. Checks for not 'End Message', if not then loop  ***
		*           (tests for and reacts to Client's sent 'End-String, "*END*".  DO-loop continues if not.)
		*/		
		}while (!received.equals("*END*"));
		
		/*
		*   ***  4. End Message received, so attempt end of connection  & return to caller  ***
		*           (tests for legitimate Client, then diag signal of status and attempts closing of Socket.
		*            Then attempts return to calling code.  First setup Error-handler:)
		*/
		try
		{
			if (client!=null)
			{
				System.out.println("Closing down connection...");
				client.close();
			}
		}
		catch(IOException ioEx)
		{
			System.out.println("Unable to disconnect!");
		}
	}
}

